package cn.diancan.util;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.params.HttpMethodParams;

import com.baidu.yun.test.temp; 

/**
 * common page 的HttpClientHelper 
 * @author Sky
 *
 */
public class HttpClientHelper {
    
	 // 读取超时  
    private final static int SOCKET_TIMEOUT = 10000;  
    // 连接超时  
    private final static int CONNECTION_TIMEOUT = 10000;  
    // 每个HOST的最大连接数量  
    private final static int MAX_CONN_PRE_HOST = 50;  
    // 连接池的最大连接数  
    private final static int MAX_CONN = 1000;   
    /** 闲置连接超时时间, 由bean factory设置，缺省为60秒钟 */
    private final static  int defaultIdleConnTimeout = 60000; 
    
    private final static  String DEFAULT_CHARSET="UTF-8";
    
    private HttpClient _httpSSLClient;
    private HttpClient _httpClient =new HttpClient();
    private boolean ssl=false;
    
    
    public HttpClientHelper() {
	super();
    }
    
    public HttpClientHelper(HttpClient httpSSLClient) {
	super();
	this._httpSSLClient = httpSSLClient;
    }

    private HttpClient getHttpClient(String url) { 
	//url.startsWith("https")
	if(ssl){
	    return _httpSSLClient;
	}
	return _httpClient; 
    }
    
    
    
    public  String doPost(String url,Map<String,String>param ,Map<String,String> headers)throws Exception{  
	return doPost(url, param, headers, DEFAULT_CHARSET);
    }
    

    public  String doPost(String url,Map<String,String>param ,Map<String,String> headers,String charSet)throws Exception{ 
	   HttpClient httpClient = getHttpClient(url);
	   httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(CONNECTION_TIMEOUT);
	   PostMethod postMethod = doPost0(url, param, headers);
	    return toString(httpClient,postMethod, charSet);
    } 
    
    
    public PostMethod doPost0(String url,Map<String,String>param ,Map<String,String> headers){ 
	    PostMethod postMethod = new PostMethod(url);
	    postMethod.getParams().setParameter(HttpMethodParams.SO_TIMEOUT,SOCKET_TIMEOUT);
	    postMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,new DefaultHttpMethodRetryHandler());
	    Iterator<Entry<String, String>> it = param.entrySet().iterator();
	    while (it.hasNext()) {
	        Entry<String, String> entry = it.next();
	        postMethod.addParameter(entry.getKey(), entry.getValue());
	    }
	    if(null!=headers &&headers.size()>0){
		    for(Map.Entry<String, String> entry : headers.entrySet()){
			postMethod.setRequestHeader(entry.getKey(), entry.getValue()); 
		    }
	    } 
	    return postMethod;
	    // postMethod.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8");
    }
    
    
    
    
    public  String doGet(String url,Map<String,String>param ,Map<String,String> headers)throws Exception{ 
	return doGet(url, param, headers, DEFAULT_CHARSET);
    }
    
    public  String doGet(String url,Map<String,String> param,Map<String,String> headers,String charSet)throws Exception{  
	HttpClient httpClient= getHttpClient(url);
	httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(CONNECTION_TIMEOUT);
	
	HttpMethod getMethod = doGet0(url, param, headers);
	return toString(httpClient,getMethod, charSet); 
    }
    
    //60.190.252.29:9090
    //107.151.142.117:80
    //58.19.222.139:3128
    
    public void setProxy(HttpClient httpClient){
	httpClient.getHostConfiguration().setProxy("58.49.30.69", Integer.valueOf("8888"));  
	//使用抢先认证
	httpClient.getParams().setAuthenticationPreemptive(true);  
    }
    
    
    private GetMethod doGet0(String url,Map<String,String> param,Map<String,String> headers)throws Exception{
	String params = ""; 
    	if(null!=param &&param.size()>0){
		for(Map.Entry<String, String> entry :param.entrySet()){
		    params += "&" + entry.getKey() + "=" + entry.getValue();
		} 
		params ="?"+params.substring(1,params.length());
    	}
	url = url + params;
	
	//设置 Http 连接超时为5秒
	_httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(CONNECTION_TIMEOUT);
	GetMethod getMethod = new GetMethod(url);
	getMethod.getParams().setParameter(HttpMethodParams.SO_TIMEOUT,SOCKET_TIMEOUT);
	//设置请求重试处理，用的是默认的重试处理：请求三次
	getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,new DefaultHttpMethodRetryHandler());
	//压制警告
	//getMethod.getParams().setParameter("http.protocol.cookie-policy",CookiePolicy.BROWSER_COMPATIBILITY); 
	//getMethod.setRequestHeader("Connection", "keep-alive"); //解决 linux下大量close_wait
	if(null!=headers &&headers.size()>0){
	    for(Map.Entry<String, String> entry : headers.entrySet()){
		getMethod.setRequestHeader(entry.getKey(), entry.getValue()); 
	    }
	}
	return getMethod;
    }
    
    
    public File doGetDownLoadFile(String url,Map<String,String>param ,Map<String,String> headers, String filePathName) throws Exception{
	HttpClient httpClient= getHttpClient(url);
	HttpMethod httpMethod =doGet0(url, param, headers);
	return toFile(httpClient, httpMethod, filePathName); 
    }
    
    
    public File toFile(HttpClient httpClient,HttpMethod httpMethod,String filePathName) throws Exception{
	InputStream in =null;
	FileOutputStream out =null;
	File tmp = new File(filePathName);
	try {
	    	if(!tmp.getParentFile().exists()){
	    	    tmp.getParentFile().mkdirs();
	    	}
	    
		if(!tmp.exists()){
			tmp.createNewFile(); //创建文件
		}
		//执行链接
		int statusCode = httpClient.executeMethod(httpMethod);
		if (statusCode != HttpStatus.SC_OK) {
			System.err.println("Method failed: "+ httpMethod.getStatusLine());
		}
		in = httpMethod.getResponseBodyAsStream(); 
		out = new FileOutputStream(tmp);
		int b1 = 0;
	 	while ((b1 = in.read()) != -1) {
			out.write(b1);
		} 
	} catch (HttpException e) {
		// 发生致命的异常，可能是协议不对或者返回的内容有问题
		tmp=null;
		System.out.println("Please check your provided http address!");
		e.printStackTrace();
	} catch (Exception e) {
		// 发生网络异常
		tmp=null;
		e.printStackTrace(); 
	} finally {
	    try {
		if(null!=in){
		    in.close();
		}
	    } catch (Exception e) { 
		 throw e;
	    }
	    try {
		if(null!=out){
		    out.flush();
		    out.close();
		}
	    } catch (Exception e) { 
		 throw e;
	    }
	    try {
		if(null!=httpMethod){
		    httpMethod.releaseConnection();
		}
	    } catch (Exception e) { 
		e.printStackTrace();
	    }
	} 
	return tmp;
    }
    
    
    public String toString(HttpClient httpClient,HttpMethod httpMethod,String charSet) throws Exception{
	InputStream in = null;
	ByteArrayOutputStream out =null;
	try { 
	    int statusCode = httpClient.executeMethod(httpMethod);
	    if (statusCode != HttpStatus.SC_OK) { 
	        throw new Exception("Method failed: " + httpMethod.getStatusLine());
	    }
	    in = httpMethod.getResponseBodyAsStream();
	    int b1 = 0;
	    out = new ByteArrayOutputStream();
	    while ((b1 = in.read()) != -1) {
	        out.write(b1);
	    }
	    byte[] b = out.toByteArray(); 
	    return new String(b, charSet); 
	} catch (Exception e) { 
	   throw e;
	}finally {
	    try {
		if(null!=in){
		    in.close();
		}
	    } catch (Exception e) { 
		 throw e;
	    }
	    try {
		if(null!=out){
		    out.flush();
		    out.close();
		}
	    } catch (Exception e) { 
		 throw e;
	    }
	    try {
		if(null!=httpMethod){
		    httpMethod.releaseConnection();
		}
	    } catch (Exception e) { 
		e.printStackTrace();
	    }
	}
    }
    
}
